from channels.generic.websocket import AsyncWebsocketConsumer
from channels.exceptions import StopConsumer
# from .models import Book
import json
from tcp_task import tcp_service
from asgiref.sync import async_to_sync
from channels.layers import get_channel_layer
channel_layer = get_channel_layer()
# 这里是将数据库的查询操作变为异步的操作
# @sync_to_async
# def get_book_list():
#     return list(Book.objects.all())
import struct
def floatToList(float_value):#小数转字符列表
    # 将浮点数转换为二进制表示
    # binary = struct.pack('!f', float_value)#参数'!f'表示使用大端字节序
    binary = struct.pack('f', float_value)
    # 将二进制表示转换为十六进
    hex_array = [int(b) for b in binary]#int整数表示  hex字符表示
    return hex_array
def SumCheck(data,length):#按字节计算校验和
    checksum = 0
    for i in range(0, length):
        checksum += data[i]
        checksum &= 0xFF  # 强制截断
    return checksum
list_group = []

class ChatConsumer(AsyncWebsocketConsumer):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.connected = False  # 增加一个标志来表示是否有连接进入
        self.deviceId=None
        self.socket=None
    #region # WebSocket连接处理
    async def connect(self):
        # 接受客户端连接
        await self.accept()
        self.connected = True  # 设置连接标志为True
        print('WebSocket连接已建立')
        # print(self.scope)
        # self.channel_name=str(self.scope['client'])
        print(self.channel_name)
        # 启动异步任务
        # await self.channel_layer.group_add("book_update")
        # asyncio.create_task(self.send_book_list_periodically())
        # await self.channel_layer.group_add("my_group", self.channel_name)
    async def disconnect(self, close_code):
        # 连接断开时的处理
        self.connected = False  # 设置连接标志为False
        
        print('这里关闭了页面')
        raise StopConsumer()
    async def receive(self, text_data):
        data = json.loads(text_data)
        print(data)
        msgType = data.get('msgType', 'unknown')
        content = data.get('content', '')

        # 根据消息类型进行处理
        if msgType == 'msgType_WebSocketDebug':
            # 处理消息
            print(f"Received message: {content}")

            # 可以选择发送回复给前端
            await self.send(text_data=json.dumps({
                'message': f'Message received! : {content}',
                'msgType': 'msgType_WebSocketDebug'
            }))
        elif msgType == 'msgType_TcpDebug':
            print(f"Received message: {content}")
            deviceId = data.get('deviceId', 'unknown')
            foundDevice = False
            for device_socket in tcp_service.list_connectedDevice:
                if device_socket['device_id'] == deviceId:
                    message = f"设备{deviceId}: {content}"
                    device_socket['socket'].sendall(message.encode('gbk'))
                    await self.send(text_data=json.dumps({
                        'message': f'Message received! : {content}',
                        'msgType': 'msgType_TcpDebug'
                    }))
                    foundDevice = True
                    break
            if not foundDevice:
                print(f"设备{deviceId}未找到")
                await self.send(text_data=json.dumps({
                    'message': f"设备{deviceId}未找到",
                    'msgType': 'msgType_TcpDebug'
                }))
        elif msgType == 'msgType_ChooseDevice':   
            self.deviceId = content
            foundDevice = False
            for device_socket in tcp_service.list_connectedDevice:
                if device_socket['device_id'] == content:
                    self.socket = device_socket['socket']
                    foundDevice = True
                    print(f"当前socket为{self.socket}")
            if not foundDevice:
                print(f"设备{deviceId}未找到")
            for groupname in list_group:
                print(f'移除{groupname}',list_group)
                list_group.remove(groupname)
                await self.channel_layer.group_discard(groupname, self.channel_name)
            groupname= f"group_{content}"
            list_group.append(groupname)
            await self.channel_layer.group_add(groupname, self.channel_name)
            # await self.send(text_data=json.dumps({
            #     'message': f'Message received! : {content}',
            #     'msgType': 'msgType_ChooseDevice'
            # }))
        elif msgType == 'msgType_Cmd':
            # print(f"Received message: {content}")
            if content == 'stop':
                self.fuc_agv_stop()
            elif content == 'forward':
                lineSpeed=data['lineSpeed']
                self.fuc_agv_moveForward(lineSpeed)
            elif content == 'backward':
                lineSpeed=data['lineSpeed']
                self.fuc_agv_moveBack(lineSpeed)
            elif content == 'turnLeft':
                rateSpeed=data['rateSpeed']
                self.fuc_agv_turnLeft(rateSpeed)
            elif content == 'turnRight':
                rateSpeed=data['rateSpeed']
                self.fuc_agv_turnRight(rateSpeed)
            elif content == 'obstacle_ignore':
                enable=data['enable']
                self.fuc_obstacle_ignore(enable)
    #endregion
    #region # TCPsocket数据发送
    def fuc_serial_send(self,cmd_id,cmd_data):
        cmd_header = [0x50, 0x43]
        cmd_length = [0x00, 0x00]
        cmd_check = [0x00]
        cmd_end = [0xda]
        cmd_length[1]=len(cmd_data)+8
        sendData0=cmd_header+cmd_length+cmd_id+cmd_data
        cmd_check[0]=SumCheck(sendData0,cmd_length[1]-2)
        sendData1=sendData0+cmd_check+cmd_end
        sendData2=bytes(sendData1)
        self.socket.send(sendData2)
    #endregion
    #region # AGV运动控制
    def fuc_agv_moveForward(self,lineSpeed):#前进
        cmd_id=[0x40,0x60]
        rateSpeed=0
        lineSpeed=abs(lineSpeed)
        cmd_data=[0x1F,]+floatToList(lineSpeed)+floatToList(rateSpeed)       
        self.fuc_serial_send(cmd_id,cmd_data)
    def fuc_agv_moveBack(self,lineSpeed):#后退
        cmd_id=[0x40,0x60]
        lineSpeed=-abs(lineSpeed)
        rateSpeed=0
        cmd_data=[0x1F,]+floatToList(lineSpeed)+floatToList(rateSpeed)       
        self.fuc_serial_send(cmd_id,cmd_data)
    def fuc_agv_turnLeft(self,rateSpeed):#正转
        cmd_id=[0x40,0x60]
        lineSpeed=0
        rateSpeed=abs(rateSpeed)
        cmd_data=[0x1F,]+floatToList(lineSpeed)+floatToList(rateSpeed)       
        self.fuc_serial_send(cmd_id,cmd_data)
    def fuc_agv_turnRight(self,rateSpeed):#反转
        cmd_id=[0x40,0x60]
        lineSpeed=0
        rateSpeed=-abs(rateSpeed)
        cmd_data=[0x1F,]+floatToList(lineSpeed)+floatToList(rateSpeed)       
        self.fuc_serial_send(cmd_id,cmd_data)
    def fuc_agv_stop(self):#停止
        cmd_id=[0x40,0x60]
        lineSpeed=0
        rateSpeed=0
        cmd_data=[0x1F,]+floatToList(lineSpeed)+floatToList(rateSpeed)       
        self.fuc_serial_send(cmd_id,cmd_data)
    def fuc_obstacle_ignore(self,enable):# 配置雷达避障
        cmd_id=[0x40,0x55]
        cmd_data=[0x00,0x00]
        if(enable):
            cmd_data=[0x01,0x00]
        self.fuc_serial_send(cmd_id,cmd_data)
    #endregion
    async def tips(self,type,msg):
        await self.send(text_data=json.dumps({
            'message': "提示的消息",
            'msgType': 'msgType_Tips'
        }))
    async def websocket_sendmessage(self, event):
        print(event)
        await self.send(text_data=json.dumps({
            'message': "监听来自Layer的消息",
            'msgType': 'msgType_TcpDebug'
        }))
        print('监听来自Layer的消息')
    async def chat_message(self,event):

        # print('发送到网页端',event['message'])
        await self.send(text_data=json.dumps({
            'message': event['message'],
            'msgType': event['msgType']
        }))
    def hlly(self):
        print('hlly')

# # 创建一个新的异步方法来全局发送消息
async def broadcast_message(deviceId,msgType,message):
    # print('广播消息',deviceId,msgType,message)
    await channel_layer.group_send(
        f'group_{deviceId}',
        {
            'type': 'chat.message',
            'msgType': msgType,
            'message': message
        }
    )